package org.custom.spring.boot.security.utils;

import cn.hutool.core.util.ArrayUtil;
import org.cleaver.spring.application.ApplicationContextUtil;
import org.custom.spring.boot.datasource.exception.TipException;
import org.custom.spring.boot.security.mapper.SystemUserMapper;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Collections;
import java.util.Date;
import java.util.Optional;

import static org.cleaver.basic.constant.CleaverConstant.EMPTY;
import static org.custom.spring.boot.security.constant.SecurityConstant.AUTOMATIC_LOGIN;

/**
 * spring-boot-security相关工具类
 *
 * @author LiKun
 * @date 2021/11/8 21:19
 */
public final class SecurityUtil {
    public static final String UNDERSCORE = "_";
    /**
     * 默认的空认证数据
     */
    private static final Authentication EMPTY_AUTHENTICATION = new UsernamePasswordAuthenticationToken(EMPTY, EMPTY, Collections.emptyList());

    private SecurityUtil() {
        throw new AssertionError(String.format("No %s instances for you!", SecurityUtil.class));
    }

    /**
     * 获取存放在 Redis 中的自动登录的 Key 值
     *
     * @param id 用户ID
     * @param iP 用户IP地址
     *
     * @return Key 值
     */
    public static String getAutomaticKey(String id, String iP) {
        return SecurityUtil.concatTargetStr(AUTOMATIC_LOGIN, id, iP);
    }

    /**
     * 获取当前用户的凭证信息
     *
     * @return 凭证
     */
    public static String getCredentials() {
        return SecurityUtil.getAuthentication().getCredentials().toString();
    }

    /**
     * 获取当前数据库时间
     *
     * @return 当前时间
     */
    public static Date getCurrentTime() {
        return ApplicationContextUtil.getBean(SystemUserMapper.class).selectCurrentTime();
    }

    /**
     * 获取当前登录用户ID
     *
     * @return 登录用户ID
     */
    public static String getCurrentUserId() {
        Object value = SecurityUtil.getAuthentication().getPrincipal();
        return Optional.ofNullable(value).orElseThrow(() -> new TipException("获取当前登录用户ID失败")).toString();
    }

    /**
     * 获取认证数据
     *
     * @return 认证数据
     */
    public static Authentication getAuthentication() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return Optional.ofNullable(authentication).orElseThrow(() -> new InsufficientAuthenticationException(EMPTY));
    }

    /**
     * 将给定的字符串拼接在一起
     *
     * @param strs 给定的字符串
     *
     * @return 结果
     */
    public static String concatTargetStr(String... strs) {
        if (ArrayUtil.isEmpty(strs)) {
            return EMPTY;
        } else {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < strs.length - 1; i++) {
                builder.append(strs[i]);
                builder.append(UNDERSCORE);
            }
            return builder.append(strs[strs.length - 1]).toString().intern();
        }
    }
}
